<template>
    <div class="box-cmd">
        <el-drawer :modal="false" :modal-append-to-body="false" :wrapperClosable="false" :title="'测试打开'" 
                :visible.sync="shellDrawerVisible" :direction="direction" size="100%" :before-close="handleClose">

            <div class="box-info" ref="box-info">
                <div class="cmd-item" v-for="(requestItem,index) in shellArray" :key="index">
                    <p class="cmd-item-request" @click="focusLine(index)">
                        <span class="cmd-item-server">{{requestItem.server}}({{requestItem.db}}) &gt;&gt;&gt;：</span><span class="cmd-item-param" 
                        ref="shellItem" :contenteditable="requestItem.contenteditable" v-html="requestItem.command" 
                        @keyup.enter="sendCommend($event,requestItem)" 
                        @keyup.up="commendHistoryChose(requestItem,1,$event)" 
                        @keyup.down="commendHistoryChose(requestItem,2,$event)"></span>
                    </p>
                    <pre class="cmd-item-result">{{requestItem.result}}</pre>
                </div>
            </div>
            <div class="box-operating">
                <el-button type="primary" size="small" @click="cleanBox">清空</el-button>
                <el-button type="primary" size="small" @click="handleClose">关闭</el-button>
            </div>
        </el-drawer>
    </div>
</template>

<script>
import splitargs from 'splitargs';
export default {
    props:["shellDrawerVisible","redisClient","connection"],
    data(){
        return {
            finalMessage:{
                connectionError:"Connection failed.",
                unknownCommand:"Unknown command.",
                emptyResylt:"(empty list or set)"
            },
            direction:"ltr",
            shellArray:[],
            currentIndex:0,
            upDownDisable:false,
            currentDb:0
        }
    },
    created(){
        this.createNewItem();
    },
    watch:{
        redisClient(newValue,oldValue){
            if(newValue!==null&&oldValue===null){
                this.createNewItem();
            }
        }
    },
    methods:{
        //聚焦
        focusLine(index){
            this.$refs["shellItem"][index].focus()
        },
        //创建新的item
        createNewItem(){
            var requestItem={server:this.connection.name,command:"",result:"",contenteditable:true,db:this.currentDb}
            this.shellArray.push(requestItem)
            this.currentIndex=this.shellArray.length-1;
            this.$nextTick(function () {
                setTimeout(()=>{
                    this.$refs["shellItem"][this.currentIndex].focus()
                },100)
            })  
        },
        //关闭窗口
        handleClose(){
            this.$emit("close")
        },
        //清屏
        cleanBox(){
            this.shellArray=[];
            this.createRequest()
        },
        //发送命令
        sendCommend(event,requestItem){
            let commandLine=event.target.outerText.replace(/^\s+|\s+$/g, '')
            let paramArray=splitargs(commandLine)
            requestItem.command=commandLine
            let result=this.execCommand(this.redisClient,paramArray)
            requestItem.contenteditable=false
            if(typeof result==='string'){
                requestItem.result=result
                this.createNewItem();
            }else{
                result.then((res)=>{
                    if(paramArray[0]==='select'){
                        this.currentDb=parseInt(paramArray[1])
                    }
                    if(res.length>0){
                        requestItem.result=this.resolveResult(res)
                    }else{
                        requestItem.result=this.finalMessage.emptyResylt
                    }
                    this.createNewItem();
                }).catch((e)=>{
                    requestItem.result=e.message
                    this.createNewItem();
                })
            }
        },
        //执行命令
        execCommand(client,paramArray=[]){
            if(!client){
                return this.finalMessage.connectionError
            }
            let key=paramArray[0]?paramArray[0].toLowerCase():''
            if(key==='' || typeof client[key]!=='function'){
                return this.finalMessage.unknownCommand
            }
            return client[key](...paramArray.slice(1))
        },
        //解析结果
        resolveResult(result) {
            let append = '';
            if (result === null) {
                append = `${null}\n`;
            }
            else if (typeof result === 'object') {
                const isArray = !isNaN(result.length);
                for (const i in result) {
                    if (typeof result[i] === 'object') {
                        append += this.resolveResult(result[i]);
                    }
                    else {
                        append += `${(isArray ? '' : (`${i}\n`)) + result[i]}\n`;
                    }
                }
            }
            else {
                append = `${result}\n`;
            }
            return append;
        },
        //上下浏览历史记录
        commendHistoryChose(requestItem,type,dom){
            if(!this.upDownDisable){
                this.upDownDisable=true
                //上一个命令
                if(type===1){
                    if((this.currentIndex-1)>=0){
                        this.currentIndex=this.currentIndex-1;
                        requestItem.command=this.shellArray[this.currentIndex].command
                    }
                }
                //下一个命令
                if(type==2){
                    if((this.currentIndex+1)<this.shellArray.length){
                        this.currentIndex=this.currentIndex+1;
                        requestItem.command=this.shellArray[this.currentIndex].command
                    }
                }
                //光标定位到命令尾部
                this.$nextTick(()=>{
                　　this.keepLastIndex(dom.target)
                    this.upDownDisable=false
                })
            }
        },
        keepLastIndex(obj) {
            //光标定位
        　　if (window.getSelection) {
        　　　　obj.focus();
        　　　　var range = window.getSelection();
        　　　　range.selectAllChildren(obj);
        　　　　range.collapseToEnd();
        　　} else if (document.selection) {
        　　　　var range = document.selection.createRange();
        　　　　range.moveToElementText(obj);
        　　　　range.collapse(false);
        　　　　range.select();
        　　}
        }
    }
}
</script>

<style scoped>
.box-cmd >>> .el-drawer__header span:focus,.box-cmd >>>.el-drawer:focus{
    outline: none;
}
.cmd-item{
    font-size: 12px;
    font-family: "微软雅黑";
    margin-bottom: 10px;
}
.cmd-item p{
    margin: 0px 0px 0px 5px;
}
.cmd-item-request >>> .el-input{
    display: inline-block;
}
.cmd-item-request >>> .el-input__inner{
    border: none;
}
.box-cmd >>> .el-drawer__body{
    height: 100%;
}
.cmd-item-request *:focus{
    outline: none;
}
.box-info{
    height: 92%;
    overflow-y: scroll;
    background-color: black;
    color: white;
    padding: 5px;
}
.cmd-item-result{
    margin: 5px 0px 0px 15px;
}
.box-operating{
    margin: 5px 5px 0px 0px;
    text-align: end;
}
</style>